import utilNodeColor from './nodeColor';
import utilNodeGroupColor from './nodeGroupColor';
import utilNodeImage from './nodeImage';
import cytoscape from 'cytoscape';
import iconKc135 from '../assets/img/KC-135.jpg';
import iconB2 from '../assets/img/B-2.jpg';
import iconB52 from '../assets/img/B-52.jpg';
import iconE3 from '../assets/img/E-3.jpg';
import iconE767 from '../assets/img/E-767.jpg';
import imgStat from '../assets/img/stat.png';
import utils from '../utils';
import coseBilkent from 'cytoscape-cose-bilkent';
import api from '../api/index';

cytoscape.use(coseBilkent);

class Graph {
    constructor() {
        this.model = undefined;
        this.rootIcon = iconKc135;
        this.defaultLevel = 2;
        this.defaultLimit = 10;
        this.nodeTapped = undefined;
        
        this.nodeColor = {};

        this.nodesInTree = {};
    }

    filterEntity(nodes, links) {
        var newNodes = [];
        var newLinks = [];
        var hashNode = {};

        var nodesToBeRemoved = {};
        var hashLinks = [];
        links.forEach((value, key) => {
            var patt1 = new RegExp('spectrogram');
            if (patt1.test(value['source'])) {
                nodesToBeRemoved[value['target']] = value;
            }
        });

        nodes.forEach(element => {
            if (nodesToBeRemoved[element.id] === undefined && hashNode[element.id] === undefined) {
                newNodes.push(element);
                hashNode[element.id] = '';
            }
        });
        links.forEach(element => {
            var linkId = 'e_' + element.source + '_' + element.target;
            if (hashNode[element.source] !== undefined && hashNode[element.target] !== undefined && hashLinks[linkId] === undefined) {
                newLinks.push(element);
            }
        });

        return {nodes:newNodes, links:newLinks};
    }

    filterTarget(target, nodes, links) {
        var that = this;
        var listException = that.getTargetExceptionList(target);
        var newNodes = {};
        var newLinks = {};
        var nodesToBeRemoved = {};

        for (var key in nodes) {
            var valid = true;
            for (var i = 0; i < listException.length; i++) {
                if (nodes[key].name.indexOf(listException[i]) > -1) {
                    valid = false;
                    nodesToBeRemoved[key] = '';
                    break;
                }
            }

            if (valid) {
                newNodes[key] = nodes[key];
            }
        }

        for (var key in links) {
            if (nodesToBeRemoved[links[key].source] === undefined && nodesToBeRemoved[links[key].target] === undefined) {
                newLinks[key] = links[key];
            }
        }

        return {nodes:newNodes, links:newLinks};
    }

    getTargetExceptionList(target) {
        var arr = [
            'B-2', 'B2',
            'B-52', 'B52',
            'E-3', 'E3',
            'E-767', 'E767',
            'KC-135', 'KC135'
        ];
        switch (target) {
            case 'B-2': case 'B2':
                arr.splice(0, 2);
                break;
            case 'B-52': case 'B52':
                arr.splice(2, 2);
                break;
            case 'E-3': case 'E3':
                arr.splice(4, 2);
                break;
            case 'E-767': case 'E767':
                arr.splice(6, 2);
                break;
            case 'KC-135': case 'KC135':
                arr.splice(8, 2);
                break;
            default:
                arr.splice(0, 2);
                break;
        }
        return arr;
    }

    filterSingleNodes(graphData, nodes, links) {
        var that = this;
        that.nodesInTree = {};
        var data = that.parseData(graphData);

        var nodesNew = {};
        var linksNew = {};

        for (var key in nodes) {
            if (that.nodesInTree[nodes[key].id] !== undefined && nodes[key].label !== 'object_kg:俯仰角:pitch_angle' && nodes[key].label !== 'object_kg:方位角:azimuth_anglee') {
                nodesNew[key] = nodes[key];
            }
        }

        for (var key in links) {
            if (that.nodesInTree[links[key].source] !== undefined && that.nodesInTree[links[key].target] !== undefined) {
                linksNew[key] = links[key];
            }
        }

        return {nodes:newNodes, links:newLinks};
    }

    parseData(dataRaw) {
        var data = undefined;
        var nodeRoot = undefined;
        for (var key in dataRaw.nodes) {
            if (key.indexOf('target_object_') > -1) {
                nodeRoot = {};
                nodeRoot.info = dataRaw.nodes[key];
                nodeRoot.isRoot = true;
                nodeRoot.style = {
                    fill: 'red'
                };
                nodeRoot.index = nodeRoot.info.id
                nodeRoot.id = nodeRoot.info.id + Date.now();
                nodeRoot.data = {collapsed: false};
                this.nodesInTree[nodeRoot.info.id] = '';
                break;
            }
        }
        if (nodeRoot) {
            data = nodeRoot;
            this.parseRoot(data, dataRaw);
        }
        return data;
    }

    parseRoot(root, dataRaw) {
        var subs = [];
        Object.keys(dataRaw.links).forEach(keyLink => {
            var link = dataRaw.links[keyLink];
            if (link.source === root.index) {
                Object.keys(dataRaw.nodes).forEach(keyNode => {
                    if (keyNode === link.target) {
                        var sub = {};
                        sub.info = dataRaw.nodes[keyNode];
                        sub.link = link;
                        sub.index = sub.info.id;
                        sub.id = sub.info.id + Date.now() + Math.random();
                        sub.data = {collapsed: false};
                        subs.push(sub);
                        this.nodesInTree[sub.info.id] = '';
                    }
                });
            }
        });
        if (subs.length > 0) {
            root.children = subs;
            root.children.forEach(element => {
                // console.log(element.id);
                this.parseRoot(element, dataRaw);
            });
        }
    }

    create(containerId, nodes, links, groupedColor) {
        var that = this;
        that.groupedColor = groupedColor;
        if (utils.isNull(document.querySelector('#' + containerId))) {
            return;
        }

        for (var key in nodes) {
            if (nodes[key]['文件地址'] !== undefined) {
                if (nodes[key]['file_path'] === undefined) {
                    nodes[key]['file_path'] = nodes[key]['文件地址'];
                }
                delete nodes[key]['文件地址'];
            }
        }

        //处理边
        var bflink = links;
        var aflink = new Array();
        // console.log(bflink);
        for (var key in bflink) {
            aflink.push(bflink[key]);	//获取对应的value值
        }
        
        //处理节点
        var bfnode = nodes;
        var afnode = new Array();
        for (var key in bfnode) {
            afnode.push(bfnode[key]);	//获取对应的value值
        }

        //剔除独立节点
        //挑选元素；删除独立节点	
        // var newnode = afnode.slice(0,150);
        // var newlink = aflink.slice(0,600);
        // //剔除独立节点
        // var select_arr1 = new Array();
        // var select_arr2 = new Array();
        // var newnode1 = new Array();

        // newlink.forEach((value, key) => {
        //     select_arr1.push(value['source']);      
        //     select_arr2.push(value['target']);
        // });
        // Object.assign({}, newnode1, newnode);

        // newnode1.forEach((value, key) => {
        //     var inele = value.id;
        //     var index1 = select_arr1.indexOf(inele);
        //     var index2 = select_arr2.indexOf(inele);
        //     if(index1 == -1 && index2 == -1) {
        //         newnode.splice(newnode.indexOf(inele),1);
        //     }	
        // });

        // //剔除独立节点
        var select_arr1 = new Array();
        var select_arr2 = new Array();
        var newnode = new Array();
        var newlink = new Array();

        aflink.forEach((value, key) => {
            select_arr1.push(value['source']);      
            select_arr2.push(value['target']);
        });

        var nodesToBeRemoved = {};
        afnode.forEach((value, key) => {
            var inele = value.id;
            var index1 = select_arr1.indexOf(inele);
            var index2 = select_arr2.indexOf(inele);
            // if(index1 >= 0 || index2 >= 0) {
                newnode.push(afnode[key]);
            // }
        });
        aflink.forEach((value, key) => {
            var patt1 = new RegExp('spectrogram');
            if (patt1.test(value['source'])) {
                nodesToBeRemoved[value['target']] = value;
            }
            else {
                newlink.push(aflink[key]);
            }
        });

        var cynode = new Array();
        var cylink = new Array();
        newnode.forEach((value, key) => {
            var info = Object.assign({}, value);
            // info.color = that.nodeColor[info.id];
            info.color = utilNodeColor[info.label];
            if (that.groupedColor) {
                if (info.group === undefined) {
                    info.color = utilNodeGroupColor[''];
                }
                else {
                    info.color = utilNodeGroupColor['' + info.group] === undefined ? utilNodeGroupColor[''] : utilNodeGroupColor['' + info.group];
                }
            }
            info.shortName = info.name.length > 5 ? info.label.split(':')[1] : info.name;
            if (nodesToBeRemoved[info.id] === undefined) {
                cynode.push(
                    { data:info }
                );
            } 
        });
        newlink.forEach((value, key) => {
            cylink.push({
                data:
                {
                    id:'e_' + value['source'] + '_' + value['target'],
                    relationship:value['type'].split('-')[1],
                    source:value['source'],
                    target:value['target'],
                    color:that.nodeColor[value['source']]
                }
            });  
        });
        
        if (groupedColor) {
            cynode.forEach((value, key) => {
                value.data['fileSuffix'] = '';
            });
        }
        else {
            cynode.forEach((value, key) => {
                value.data['icon'] = 'object_kg:目标型号:target_object' === value.data['label'] || 'object_kg:目标类型:target_object' === value.data['label'] ? that.getTargetIcon(value.data['name']) : '';
                value.data['src'] = value.data['file_path'] === undefined ? undefined : api.getGraphNodeImage({url: value.data['file_path']}).url;
                value.data['isImage'] = value.data['file_path'] === undefined ? '0' : '1';
                value.data['fileSuffix'] = that.getFileSuffix(value.data['file_path']);
    
                if (utilNodeImage[value.data.label] !== undefined) {
                    if (value.data['file_path'] === undefined) {
                        value.data['src'] = utilNodeImage[value.data.label];
                        value.data['isImage'] = '1';
                    }
                }
            });
        }
        console.log(cynode);
        that.cy(containerId, cynode, cylink);
    }

    cy(containerId, cynode, cylink) {
        var that = this;

        var cy = cytoscape({
            //首先进行div的绑定，绑定到id为cy这个div上进行显示
            container: document.getElementById(containerId),
            motionBlur: false,
            //定义显示图谱的节点与边的样式
            style: [
                {
                    selector: 'node', 
                    css: { 
                        'content': 'data(shortName)',
                        'color':'white',
                        'text-valign': 'center',
                        'text-outline-color': '#6699FF',
                        'background-color': 'data(color)',//'#6699FF',
                        'height': 60,
                        'width': 60,
                        'font-size':'12px',
                        // 'text-overflow': 'ellipsis',
                        'text-overflow-wrap': 'anywhere',//'whitespace',
                        "text-wrap": "wrap",
                        "text-max-width": 50,
                        'border-color': '#fff',
                        'border-width': 3
                    }
                },
                { 
                    selector: 'edge',
                //边的样式，'target-arrow-shape': 'triangle'定义箭头指向
                    css: {
                        'content': 'data(relationship)', 
                        'curve-style': 'bezier',	//曲线类型为贝塞尔曲线
                        'target-arrow-shape': 'triangle',
                        'target-arrow-color': '#CCCCCC',//'data(color)',
                        'line-color': '#CCCCCC',//'#CCCCCC','data(color)',
                        'width': 1,
                        'font-size':'6px',
                        'edge-text-rotation': 'autorotate',
                        'color': '#ccc',
                        'background-color': '#000'
                    },
                    // style: {
                    //         return ele.data('relationship');
                    //     }
                    // }
                }, 
                {
                    selector: '.autorotate',
                    style: {
                        "edge-text-rotation": "autorotate"
                    }
                },
                //画图设置；
                {   
                    selector: 'node[label = "object_kg:光谱曲线图:spectrogram"]', 
                    css: {
                        'background-image': 'data(src)',//'data(src)',//data(file_path)
                        'height': 60,
                        'width': 60,
                        // 'height': 80,
                        // 'width': 100,
                        // 'shape': 'rectangle',
                        'background-fit': 'cover',
                        'border-color': '#fff',
                        'color':'#000',
                        'font-size':'10px',
                        'content': '光谱曲线图', //全部name，浮动显示；
                    }
                },
                //画图设置；
                {   
                    selector: 'node[isImage = "1"]', 
                    css: {
                        'background-image': 'data(src)',//imgStat,//'data(src)',//data(file_path)
                        'height': 60,
                        'width': 60,
                        // 'height': 80,
                        // 'width': 100,
                        // 'shape': 'rectangle',
                        'background-fit': 'cover',
                        'border-color': '#fff',
                        'color':'#000',
                        'font-size':'12px',
                        'content': '', //全部name，浮动显示；数据分析图
                    }
                },
                {   
                    selector: 'node[fileSuffix != ""]', 
                    css: {
                        'height': 30,
                        'width': 30,
                        'background-fit': 'cover',
                        'border-color': '#fff',
                        'color':'#000',
                        'font-size':'12px',
                        'content': 'data(fileSuffix)', //全部name，浮动显示；数据分析图
                    }
                },
                {
                    selector: 'node[label = "object_kg:RCS数据:rcs_data"]', 
                    css: {'height': 30,
                        'width': 30,
                        'background-fit': 'cover',
                        'border-color': '#fff', //'#000','data(color)'
                        'border-opacity': 0.5,
                        'text-outline-width': 2,
                        'text-outline-color': '#d0413e',
                        'content': '.dat', //全部name，浮动显示；
                    }
                },
                {
                    selector: 'node[label = "object_kg:HRRP数据:hrrp_mat_data"]', 
                    css: {'height': 30,
                        'width': 30,
                        'background-fit': 'cover',
                        'border-color': '#fff', //'#000','data(color)'
                        'border-opacity': 0.5,
                        'text-outline-width': 2,
                        'text-outline-color': '#d0413e',
                        'content': '.mat', //全部name，浮动显示；
                    }
                },
                {
                    selector: 'node[label = "object_kg:目标型号:target_object"]', 
                    css: {'height': 80,
                        'width': 80,
                        'background-fit': 'cover',
                        'border-color': '#fff', //'#000','data(color)',
                        'border-opacity': 0.5,
                        'text-outline-width': 2,
                        'text-outline-color': '#d0413e',
                        'background-image': 'data(icon)', //后续从文件获取，that.rootIcon
                        //'content': '光谱曲线图', //全部name，浮动显示；
                        'content': 'data(name)', //全部name，浮动显示；
                    }
                },
                {
                    selector: 'node[label = "object_kg:目标类型:target_object"]', 
                    css: {'height': 80,
                        'width': 80,
                        'background-fit': 'cover',
                        'border-color': '#fff', //'#000','data(color)',
                        'border-opacity': 0.5,
                        'text-outline-width': 2,
                        'text-outline-color': '#d0413e',
                        'background-image': 'data(icon)', //后续从文件获取，that.rootIcon
                        //'content': '光谱曲线图', //全部name，浮动显示；
                        'content': 'data(name)', //全部name，浮动显示；
                    }
                },
                {   
                    selector: 'node:selected', 
                    css: {
                        'height': 130,
                        'width': 130,
                        'font-size':'18px',
                        'border-color': '#fff',
                        'border-width': 10,
                        "text-max-width": 100
                    }
                },
            ],
            //图谱元素
            elements: {
                //节点数据，节点数据中id为必填项，另外name与label为自选项
                nodes: cynode,
                //边数据，source与target为必选项
                edges: cylink
            },
            //布局方式，还有circle...等
            layout: { name: 'cose-bilkent'} 
        });
    
        that.model = cy;
        that.handleLayout(true);
    }

    add(baseNode, nodes, links) {
        var that = this;
        var oldx = baseNode.position.x;
        var oldy = baseNode.position.y;

        for (var key in nodes) {
            if (nodes[key]['文件地址'] !== undefined) {
                if (nodes[key]['file_path'] === undefined) {
                    nodes[key]['file_path'] = nodes[key]['文件地址'];
                }
                delete nodes[key]['文件地址'];
            }
        }

        var groups = [];
        var nodesToBeRemoved = {};
        for (var key in links) {
            var linkId = 'e_' + links[key].source + '_' + links[key].target;
            var group = { 
                group: 'edges',
                data: { 
                    id: linkId,
                    relationship: links[key].type.split('-')[1],
                    source:links[key].source, 
                    target:links[key].target,
                    color:'#ccc'
                    // color:that.nodeColor[data.links[key].source]
                } 
            };
            var patt1 = new RegExp('spectrogram');
            if (patt1.test(links[key].source)) {
                nodesToBeRemoved[links[key].target] = links[key];
            }
            else {
                groups.push(group);
            }
        }
        var i = 0;
        for (var key in nodes) {
            var group = { 
                group: 'nodes', 
                data: { id: nodes[key].id, 
                    label:nodes[key].label, 
                    name:nodes[key].name,
                    shortName: nodes[key].name.length > 5 ? nodes[key].label.split(':')[1] : nodes[key].name,
                    // color:that.nodeColor[data.nodes[key].id],
                    // color:utilNodeColor[data.nodes[key].label],
                    icon:'object_kg:目标型号:target_object' === nodes[key]['label'] || 'object_kg:目标类型:target_object' === nodes[key]['label'] ? that.getTargetIcon(nodes[key]['name']) : '',
                    color:that.getNodeColor(nodes[key]),
                    src:nodes[key]['file_path'] === undefined ? undefined : api.getGraphNodeImage({url: nodes[key]['file_path']}).url,
                    isImage:nodes[key]['file_path'] === undefined ? '0' : '1',
                    fileSuffix:that.getFileSuffix(nodes[key]['file_path'])
                }, 
                // position: { 
                //     x: oldx + 100 * i, 
                //     y: oldy + 100 * i 
                // } 
            };
            if (that.groupedColor) {
                group.data['icon'] = '';
                group.data['src'] = undefined;
                group.data['isImage'] = '0';
                group.data['fileSuffix'] = '';
                
                if (nodes[key].group === undefined) {
                    group.data.color = utilNodeGroupColor[''];
                }
                else {
                    group.data.color = utilNodeGroupColor['' + nodes[key].group] === undefined ? utilNodeGroupColor[''] : utilNodeGroupColor['' + nodes[key].group];
                }
            }
            if (utilNodeImage[nodes[key].label] !== undefined) {
                if (nodes[key]['file_path'] === undefined) {
                    group.data.src = utilNodeImage[nodes[key].label];
                    group.data.isImage = '1';
                }
            }
            if (nodesToBeRemoved[nodes[key].id] === undefined) {
                groups.push(group);
            } 
            i++;
        }
        console.log(groups);
        that.model.add(groups);

        that.handleLayout();
    }

    handleLayout() {
        var layout = this.model.layout({
            name: 'cose-bilkent',
            idealEdgeLength: 100,
            nodeRepulsion: 70000,
            edgeElasticity: 0.1,
            gravity: 10,
            nestingFactor: 5,
            animate: 'end',
            animationEasing: 'ease-out',
            animationDuration: 1000,
            randomize: false
        });
    
        // if (inition === true) {
        //     return;
        // }
        layout.run();
    }

    getFileSuffix(src) {
        var suffix = '';
        if (src !== undefined) {
            var arr = src.split('.');
            var name = arr[arr.length - 1];
            if (name !== 'png' && name !== 'jpg' && name !== 'jpeg') {
                suffix = '.' + name;
            }
        }
        return suffix;
    }

    getTargetIcon(name) {
        var icon = iconKc135;
        switch (name) {
            case 'B-2': case 'B2':
                icon = iconB2;
                break;
            case 'B-52': case 'B52':
                icon = iconB52;
                break;
            case 'E-3': case 'E3':
                icon = iconE3;
                break;
            case 'E-767': case 'E767':
                icon = iconE767;
                break;
            case 'KC-135': case 'KC135':
                icon = iconKc135;
                break;
            default:
                icon = iconKc135;
                break;
        }
        return icon;
    }

    getNodeColor(node) {
        return utilNodeColor[node.label];
    }
}

var graph = new Graph();
window.graph = graph;

export default graph;